package com.skyworthclub.competition.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.skyworthclub.competition.beans.User;
import com.skyworthclub.competition.beans.dto.ResetPasswordDto;
import com.skyworthclub.competition.beans.dto.SendValidationCodeDto;
import com.skyworthclub.competition.beans.dto.UserRegisterDto;
import com.skyworthclub.competition.service.UserService;
import com.skyworthclub.competition.utils.web.DataValidateUtil;
import com.skyworthclub.competition.utils.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * @author li
 * @version 1.0
 * @since 18-10-15 下午9:11
 * 登录注册前端控制器
 **/
@Controller
@RequestMapping("/api/auth")
public class AuthController {

    private final UserService userService;

    private final EmailService emailService;
    /**
     * 注册验证码的键
     */
    private static final String SEND_FOR_REGISTER_CODE_KEY = "registerValidationCode";
    /**
     * 重置密码获取验证码的键
     */
    private static final String SEND_FOR_RESET_PASSWORD_CODE_KEY = "resetPasswordValidationCode";
    /**
     * 会话中保存注册邮箱的键
     */
    private static final String REGISTER_EMAIL_KEY = "registerEmail";
    /**
     * 会话中保存重置密码邮箱的键
     */
    private static final String RESET_PASSWORD_EMAIL_KEY = "resetPasswordEmail";

    private static final String REGISTER_FLAG = "1";

    private static final String RESET_PASSWORD_FLAG = "2";

    @Autowired
    public AuthController(UserService userService, EmailService emailService) {
        this.userService = userService;
        this.emailService = emailService;
    }


    /**
     * 默认跳转登录页面
     * 仅供测试使用
     */
    @GetMapping("/loginPage")
    public String loginPage() {
        return "auth/login_page";
    }

    /**
     * @param userRegisterDto json数据转为数据传输对象
     * @param errors          数据校验产生的错误信息
     * @param httpSession     当前会话
     */
    @PostMapping("/register")
    public ResponseEntity<Map<String, Object>> register(@RequestBody @Valid UserRegisterDto userRegisterDto,
                                                        Errors errors,
                                                        HttpSession httpSession) {

        Map<String, Object> map = new HashMap<>(4);

        //数据校验
        ResponseEntity<Map<String, Object>> responseEntity = DataValidateUtil.validate(errors);
        if (responseEntity != null) {

            return responseEntity;

        }  else if (!userRegisterDto.getPassword().equals(userRegisterDto.getRepeatPassword())) {
            map.put("status", 400);
            map.put("message", "两次密码输入不一致");
            responseEntity = new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
            return responseEntity;
        }

        //数据预处理
        userRegisterDto.setEmail(userRegisterDto.getEmail().toLowerCase());

        //验证码校验
        String code = (String) httpSession.getAttribute(SEND_FOR_REGISTER_CODE_KEY);
        String email = (String) httpSession.getAttribute(REGISTER_EMAIL_KEY);
        if (!userRegisterDto.getValidationCode().equals(code) || !userRegisterDto.getEmail().equals(email)) {
            map.put("status", 400);
            map.put("message", "验证码错误");
            responseEntity = new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
            return responseEntity;
        }

        //检查用户是否存在
        int i = userService.selectCount(new EntityWrapper<User>().eq("username", userRegisterDto.getUsername()).or().eq("email", userRegisterDto.getEmail()));
        if (i > 0) {
            map.put("status", 400);
            map.put("message", "用户已存在！");
            responseEntity = new ResponseEntity<>(map, HttpStatus.OK);
            return responseEntity;
        }

        //注册
        boolean register = userService.register(userRegisterDto);
        //注册成功
        if (register) {
            map.put("status", 200);
            map.put("message", "注册成功");
            responseEntity = new ResponseEntity<>(map, HttpStatus.OK);
            return responseEntity;
        } else {
            map.put("status", 500);
            map.put("message", "serverError");
            responseEntity = new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR);
            return responseEntity;
        }

    }

    @PostMapping("/resetPassword")
    public ResponseEntity<Map<String, Object>> resetPassword(@RequestBody @Valid ResetPasswordDto resetPasswordDto,
                                                             Errors errors,
                                                             HttpSession httpSession) {
        Map<String, Object> map = new HashMap<>(4);
        //数据校验
        ResponseEntity<Map<String, Object>> responseEntity = DataValidateUtil.validate(errors);
        if (responseEntity != null) {

            return responseEntity;

        }  else if (!resetPasswordDto.getNewPassword().equals(resetPasswordDto.getRepeatPassword())) {
            map.put("status", 400);
            map.put("message", "两次密码输入不一致");
            responseEntity = new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
            return responseEntity;
        }
        //数据预处理
        resetPasswordDto.setEmail(resetPasswordDto.getEmail().toLowerCase());

        //从会话中获取验证码和邮箱
        String code = (String) httpSession.getAttribute(SEND_FOR_RESET_PASSWORD_CODE_KEY);
        String email = (String) httpSession.getAttribute(RESET_PASSWORD_EMAIL_KEY);
        //校验验证码和邮箱
        if (!resetPasswordDto.getEmail().equals(email) || !resetPasswordDto.getValidationCode().equals(code)) {
            map.put("status", 400);
            map.put("message", "验证码错误");
            responseEntity = new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
            return responseEntity;
        }

        //更新数据
        boolean updatePassword = userService.updatePassword(resetPasswordDto);
        if (updatePassword) {
            map.put("status", 200);
            map.put("message", "密码修改成功");
            responseEntity = new ResponseEntity<>(map, HttpStatus.OK);
            return responseEntity;
        } else {
            map.put("status", 500);
            map.put("message", "serverError");
            responseEntity = new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR);
            return responseEntity;
        }
    }


    /**
     * @param codeDto     封装邮件地址和验证码目的代码的对象
     * @param httpSession 当前会话
     *                    发送邮箱验证码
     */
    @PostMapping("/sendValidationCode")
    public ResponseEntity<Map<String, Object>> sendValidationCode(@RequestBody @Valid SendValidationCodeDto codeDto,
                                                                  Errors errors,
                                                                  HttpSession httpSession) {

        Map<String, Object> map = new HashMap<>(4);
        //验证码的目的
        String codeFor = null;
        //回话保存邮件地址的键
        String emailKey = null;
        //数据校验
        ResponseEntity<Map<String, Object>> responseEntity = DataValidateUtil.validate(errors);
        if (responseEntity != null) {
            return responseEntity;
        }
        //数据预处理
        codeDto.setEmail(codeDto.getEmail().toLowerCase());

        //注册
        if (codeDto.getSendFor().equals(REGISTER_FLAG)) {
            //检查存在性
            int count = userService.selectCount(new EntityWrapper<User>().eq("email", codeDto.getEmail()));
            if (count > 0) {
                map.put("status", 400);
                map.put("message", "邮箱已被注册！");
                responseEntity = new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
                return responseEntity;
            }
            codeFor = SEND_FOR_REGISTER_CODE_KEY;
            emailKey = REGISTER_EMAIL_KEY;
        } else if (codeDto.getSendFor().equals(RESET_PASSWORD_FLAG)) {
            //重置密码
            int count = userService.selectCount(new EntityWrapper<User>().eq("email", codeDto.getEmail()));
            if (count < 0) {
                map.put("status", 400);
                map.put("message", "邮箱未注册！");
                responseEntity = new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
                return responseEntity;
            }
            codeFor = SEND_FOR_RESET_PASSWORD_CODE_KEY;
            emailKey = RESET_PASSWORD_EMAIL_KEY;
        }


        //发送验证码
        try {
            emailService.sendValidationCodeMail(codeDto.getEmail(), codeFor, emailKey, httpSession);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("status", 500);
            map.put("message", "发送失败！");
            responseEntity = new ResponseEntity<>(map, HttpStatus.OK);
            return responseEntity;
        }
        map.put("status", 200);
        map.put("message", "发送成功");
        responseEntity = new ResponseEntity<>(map, HttpStatus.OK);
        return responseEntity;

    }

}
